home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Game-Power
/
Amiga Game-Power.iso
/
anwendungen
/
gw print
/
silobj.doc
< prev
next >
Wrap
Text File
|
1994-05-20
|
9KB
|
389 lines
/* :ts=8 */
/*
Data types used in Silver
*/
#define FAST register
#define CARD unsigned
#define GLOBAL extern
#define FRACT long
typedef UBYTE COLOR[3];
typedef struct vectors {
FRACT X;
FRACT Y;
FRACT Z;
} VECTOR;
/*
* A "FRACT" number is a 32 bit fixed point number with a 16 bit
* fractional part. (e.g. 7.25 is represented as 0x00074000)
*
* Colors are stored as 3 UBYTE values on a scale of 0 to 255.
*/
/*
This is the internal structure of Turbo Silver Objects
*/
#define PRP_SURFACE 0
#define PRP_BRUSH PRP_SURFACE + 1
#define PRP_STENCIL PRP_BRUSH + 1
#define PRP_MATTER PRP_STENCIL + 1
#define PRP_BLEND PRP_MATTER + 1
#define PRP_SMOOTH PRP_BLEND + 1
#define PRP_SHINY PRP_SMOOTH + 1
#define PRP_EXTRA PRP_SHINY + 1
#define NUM_OBJ_PROPS (PRP_EXTRA + 1)
#define ABS_ROT 1
#define ABS_SCL 2
#define LOC_ROT 4
#define LOC_SCL 8
typedef struct story {
UBYTE Path[18]; /* 18 bytes */
VECTOR Rotate; /* 12 bytes */
VECTOR Scale; /* 12 bytes */
UWORD info; /* 2 bytes */
} STORY; /* 44 bytes total */
typedef struct barfu {
UBYTE Shape; /* 1 byte */
UBYTE Parent [3]; /* 3 bytes */
ULONG Number; /* 4 bytes */
VECTOR Position; /* 12 bytes */
VECTOR A; /* 12 bytes */
VECTOR B; /* 12 bytes */
VECTOR C; /* 12 bytes */
VECTOR S; /* 12 bytes */
} SUBOBJ, *SUBPTR; /* 68 bytes total */
typedef struct object {
struct object *Parent; /* 4 bytes */
struct object *Child; /* 4 bytes */
struct object *Older; /* 4 bytes */
struct object *Younger; /* 4 bytes */
STORY *Story; /* 4 bytes */
SUBOBJ Object; /* 68 bytes */
UBYTE Props [NUM_OBJ_PROPS]; /* 8 bytes */
UBYTE Name [18]; /* 18 bytes */
UWORD PCount; /* 2 bytes */
ULONG TCount; /* 4 bytes */
VECTOR *Points; /* 4 bytes / 12 bytes */
UWORD *Connects; /* 4 bytes / 6 bytes */
SUBOBJ *Subjects; /* 4 bytes / 68 bytes */
VECTOR *Phongs; /* 4 bytes / 12 bytes */
COLOR *Diffuse; /* 4 bytes / 3 bytes */
COLOR *Reflect; /* 4 bytes / 3 bytes */
COLOR *Transmit; /* 4 bytes / 3 bytes */
} OBJECT, *OBJPTR; /* 152 bytes total */
#define OSIZE (long) sizeof (OBJECT)
#define SSIZE (long) sizeof (SUBOBJ)
#define VSIZE (long) sizeof (VECTOR)
#define SPHERE 0L
#define STENCIL 1L
#define AXIS 2L
#define FACETS 3L
#define SURFACE 4L
/*
* The 'Object' component of the 'struct object' structure
* and the 'Props[]' component, contains the necessary info
* for everything but faceted objects (i.e. spheres, surfaces,
* stencils and axes). The 'Object.Shape' field is a number
* (from the #defines above) specifying which type of object
* is described. The 'Object.Parent' and 'Object.Number' fields
* don't matter in file data. The 'Object.A', 'B', and 'C' vectors
* are the unit vectors describing the object coordinate system
* ('A' is the 'x' axis, 'B' is the 'y' axis, 'C' is the 'z').
*
* The 'Props[]' array is:
*
* Props[PRP_SURFACE] - bits 0-3 are the "surface type":
* 0 = Matte, 4 = genlock, 5 = brush
* - bit 6 is clear for phong shaded, else set
* Props[PRP_BRUSH ] - the brush number
* Props[PRP_STENCIL] - the stencil number
* Props[PRP_MATTER ] - type of matter: 0 = Air, 1 = Water,
* 2 = Glass, 3 = Crystal, 4 = Custom
* Props[PRP_BLEND ] - blending factor 0-255
* Props[PRP_SMOOTH ] - roughness factor 0-255
* Props[PRP_SHINY ] - non-zero for shiny objects
* Props[PRP_EXTRA ] - custom index of refraction 0-255
* (if Props[PRP_MATTER] == 4).
* 0 correnponds to 1.00, and 255 to 3.55
*
* The 'Diffuse', 'Reflect', and 'Transmit' fields should really
* be unions. If the object is not a "custom" (points/faces) object,
* they are really a pad byte and 3 color bytes (RGB).
*
* If the object is a "custom" - faceted - object, the 'PCount', and
* 'TCount' parameters give the number of points and faces respectively.
* The point list is pointed to by 'Points', and the face list is
* pointed to by 'Connects'. The point list is a list of 'VECTOR's,
* and the face list is a list of UWORD point number triples. The
* Colors for each face are stored in 3 COLOR lists pointed to by
* 'Diffuse', 'Reflect', and 'Transmit'. There is one COLOR
* structure for each face, in order corresponding to the face list.
*
* The routines below indicate what information actually gets read
* or written to the file, and how.
*/
/*
* These routines write the Silver object trees to the file:
*
* after opening the file ('ofile'):
*
* fprintf (ofile, "SILVER II\nOBJT\n");
* WrtNode (TheObject, ofile);
* fclose (ofile);
*
* - where 'TheObject' points to a 'struct object'.
*/
static ULONG story_header [] = { 0x53545259, (ULONG) sizeof (STORY) };
void write_node (p, fp)
OBJECT *p;
FILE *fp;
{
while (p) {
WrtNode (p, fp);
p = p->Younger;
}
fwrite ("\0", 1, 1, fp);
}
void WrtNode (p, fp)
OBJECT *p;
FILE *fp;
{
FAST ULONG i;
FAST UWORD *w;
FAST COLOR *c;
if ((long) p <= 0)
return;
fwrite ("\001", 1, 1, fp);
fwrite (p->Name, 18, 1, fp);
fwrite (&p->Object, (int) SSIZE, 1, fp);
fwrite (p->Props, NUM_OBJ_PROPS, 1, fp);
if (p->Story) {
fwrite (story_header, 8, 1, fp);
fwrite (p->Story, sizeof (STORY), 1, fp);
}
fwrite (&p->PCount, 2, 1, fp);
fwrite (&p->TCount, 4, 1, fp);
if (p->PCount) {
fwrite ("PNTS", 4, 1, fp);
fwrite (p->Points, (int) VSIZE, p->PCount, fp);
}
if (p->TCount) {
fwrite ("CNRS", 4, 1, fp);
i = p->TCount * 3L;
w = p->Connects;
while (i--)
fwrite (w++, 2, 1, fp);
i = p->TCount;
c = p->Diffuse;
while (i--)
fwrite (c++, 3, 1, fp);
i = p->TCount;
c = p->Reflect;
while (i--)
fwrite (c++, 3, 1, fp);
i = p->TCount;
c = p->Transmit;
while (i--)
fwrite (c++, 3, 1, fp);
} else {
fwrite (&p->Diffuse, 4, 1, fp);
fwrite (&p->Reflect, 4, 1, fp);
fwrite (&p->Transmit, 4, 1, fp);
}
write_node (p->Child, fp);
}
/*
* These read the Silver object trees from the file:
*
* After opening the file ('ofile'):
*
* char s[256];
* OBJECT *temp;
*
* fgets (s, 256, ofile);
* if (strncmp (s, "SILVER II", 9))
* goto oerr;
*
* fgets (s, 256, ofile);
* if (strncmp (s, "OBJT", 4))
* goto oerr;
*
* temp = LodNode (ofile);
*
*/
OBJECT *load_node (fp)
FILE *fp;
{
OBJECT *head, *prev, *curr;
head = 0L;
prev = 0L;
for (;;) {
curr = LodNode (fp);
if (!curr)
break;
if (prev)
prev->Younger = curr;
else
head = curr;
curr->Older = prev;
prev = curr;
}
return head;
}
OBJECT *LodNode (fp)
FILE *fp;
{
OBJECT *temp, *curr;
UBYTE s;
ULONG id;
FAST ULONG i;
FAST UWORD *w;
FAST COLOR *c;
if (feof (fp) || ferror (fp))
return NULL;
if (!(s = getc (fp)))
return NULL;
if (!(temp = add_node ((int) FACETS)))
return NULL;
fread (temp->Name, 18, 1, fp);
temp->Name[17] = '\0';
StringUp (temp->Name);
fread (&temp->Object, (int) SSIZE, 1, fp);
fread (temp->Props, NUM_OBJ_PROPS, 1, fp);
fread (&id, 4, 1, fp);
if (id == 0x53545259) {
fread (&id, 4, 1, fp);
if (temp->Story = AllocMem (id, 0L))
fread (temp->Story, (int) id, 1, fp);
else
fseek (fp, id, 1);
} else
fseek (fp, -4L, 1);
fread (&temp->PCount, 2, 1, fp);
fread (&temp->TCount, 4, 1, fp);
if (temp->PCount) {
fread (&id, 4, 1, fp);
if (id != 0x504e5453) {
DelNode (temp);
return NULL;
}
if (temp->Points = AllocMem (temp->PCount * VSIZE, 0L))
fread (temp->Points, (int) VSIZE, temp->PCount, fp);
else
fseek (fp, temp->PCount * VSIZE, 1);
}
if (temp->TCount) {
fread (&id, 4, 1, fp);
if (id != 0x434e5253) {
DelNode (temp);
return NULL;
}
if (temp->Connects = AllocMem (temp->TCount * 6L, 0L)) {
i = temp->TCount * 3;
w = temp->Connects;
while (i--)
fread (w++, 2, 1, fp);
} else
fseek (fp, temp->TCount * 6L, 1);
}
if (temp->TCount)
if (temp->Diffuse = AllocMem (temp->TCount * 3L, 0L)) {
i = temp->TCount;
c = temp->Diffuse;
while (i--)
fread (c++, 3, 1, fp);
} else
fseek (fp, temp->TCount * 3L, 1);
else
fread (&temp->Diffuse, 4, 1, fp);
if (temp->TCount)
if (temp->Reflect = AllocMem (temp->TCount * 3L, 0L)) {
i = temp->TCount;
c = temp->Reflect;
while (i--)
fread (c++, 3, 1, fp);
} else
fseek (fp, temp->TCount * 3L, 1);
else
fread (&temp->Reflect, 4, 1, fp);
if (temp->TCount)
if (temp->Transmit = AllocMem (temp->TCount * 3L, 0L)) {
i = temp->TCount;
c = temp->Transmit;
while (i--)
fread (c++, 3, 1, fp);
} else
fseek (fp, temp->TCount * 3L, 1);
else
fread (&temp->Transmit, 4, 1, fp);
SetSubParent (temp);
temp->Child = load_node (fp);
curr = temp->Child;
while (curr) {
curr->Parent = temp;
curr = curr->Younger;
}
return temp;
}